#include <cctype>
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
class TextQuery
{
public:
    TextQuery(size_t capacity)
    {
        _lines.reserve(capacity);
    }
    void readFile(const std::string &filename)
    {
        std::ifstream ifs(filename);
        if (!ifs)
        {
            std::cerr << "ifstream open file failed" << std::endl;
            return;
        }
        std::string line;
        int lineNumber = 1;
        while (std::getline(ifs, line))
        {
            _lines.push_back(line);
            dealLine(line);
            std::istringstream iss(line);
            std::string word;
            while (iss >> word)
            {
                ++_dict[word];
                _wordNumbers[word].insert(lineNumber);
            }
            ++lineNumber;
        }
        ifs.close();
    }
    void dealLine(std::string &line)
    {
        // Shenzhen-HK
        for (auto &ch : line)
        {
            if (!isalpha(ch))
            {
                ch = ' ';
            }
            else if (isupper(ch))
            {
                ch = tolower(ch);
            }
        }
    }
    void query(const std::string &word)
    {
        std::cout << "-------------------------" << std::endl;
        int count = _dict[word];
        std::cout << word << " occurs " << count << (count > 1 ? " times." : "time.") << std::endl;
        std::set<int> ls = _wordNumbers[word];
        for (auto &num : ls)
        {
            std::cout << "(line " << num << ") " << _lines[num - 1] << std::endl;
        }
    }

private:
    std::vector<std::string> _lines;
    std::map<std::string, std::set<int>> _wordNumbers;
    std::map<std::string, int> _dict;
};
int main(int argc, char *argv[])
{
    std::string queryWord("nihao");
    TextQuery tq(200);
    tq.readFile("dic.txt");
    tq.query(queryWord);
    return 0;
}